from cv2 import filterSpeckles
import pygame
import random
import math
from pygame import font
from pygame.constants import K_DOWN, K_LEFT, K_RIGHT, K_SPACE, K_UP
from pygame.event import clear
import os
import numpy as np

# init
pygame.init()
# 设置窗口大小
screen=pygame.display.set_mode((800,450))
# 标题
pygame.display.set_caption('星际争霸1.2')
# size=int(input('请输入尺寸'))
#当前路径
path=os.path.abspath('feiji')
size=30
# 加载图片（静态资源加载）
icon=pygame.image.load(f'{path}/fei.png')
bg=pygame.image.load(f'{path}/bgs.png')
fei=pygame.image.load(f'{path}/feiji.png')
# 设置窗口icon
pygame.display.set_icon(icon)

# 分数
score=0
# 字体对象
fonts=pygame.font.Font(f'{path}/simhei.ttf',16)
# fonts = pygame.font.SysFont("arial", 16)


# 显示分数
def showscore():
    text=f"分数:{score}"
    score_rander=fonts.render(text,True,(255,255,255))
    screen.blit(score_rander,(35,35))

# 显示对话
def showtalk(x,y):
    text='我是老王'
    fonts=pygame.font.Font(f'{path}/simhei.ttf',10)
    say_render=fonts.render(text,True,(255,255,255))
    screen.blit(say_render,(x-50,y))

# diren类
class Enemy():
    def __init__(self):
        self.img=pygame.image.load(f'{path}/di3.png')
        self.x=random.randint(0,770)
        self.y=random.randint(0,200)
        self.step=random.uniform(0.1,1)
    # 重置位置
    def reset(self):
        self.x=random.randint(0,770)
        self.y=random.randint(0,260)

# diren数量
num_enemy=6
 # 存储diren
enemy_arr=[]

# diren添加数组中
for i in range(num_enemy):
    enemy_arr.append(Enemy())

# 添加敌人
def addenemy():
    global enemy_arr
    # diren添加数组中
    for i in range(num_enemy):
        enemy_arr.append(Enemy())

#添加背景音效
pygame.mixer.music.load(f'{path}/mu(1).wav')
# 单曲循环
pygame.mixer.music.play(-1)

# 击中音效
bao_sund=pygame.mixer.Sound(f'{path}/bao.wav') 

# 飞机位置CHUSHI
feix=350
feiy=400

# 显示diren
def showenemys():
    global isover
    for e in enemy_arr:
        screen.blit(pygame.transform.scale(e.img,(40,40)),(e.x,e.y))
        # 显示文字
        # showtalk(e.x,e.y)
        if e.x<0:
            e.x=0
            e.y+=5
            e.step=-e.step
        elif e.x >770:
            e.x=770
            e.y+=5
            e.step=-e.step
        if e.y>350:
            enemy_arr.clear()
            boss_arr.clear()
            isover=True
        e.x+=e.step

isover=False


#检查是否重新开始
def restart():
    global isover
    event=pygame.event.wait()
    # 是否点击重新开始
    if event.type==pygame.MOUSEBUTTONDOWN:
        x,y=event.pos
        if isover:
            if x>355 and x<400 and y>250 and y<300:
                isover=False 
                addenemy()


# 敌人炮弹
class Dpao():
    def __init__(self,x,y):
        self.x=x
        self.y=y
        self.img=pygame.image.load(f'{path}/pao.png')
        self.step=6
    def hit(self):
        global feix,feiy,isover,score
        if (distance(self.x,self.y,feix,feiy)<20):
            enemy_arr.clear()
            # dpao_arr.clear()
            boss_arr.clear()
            score=0 
            isover=True


# 敌人炮弹存储
dpao_arr=[]
# 显示敌人炮弹
def showdipao():
    global dpao_arr
    for e in dpao_arr:
        screen.blit(e.img,(e.x,e.y))
        e.y+=e.step
        e.hit()
        if e.y<0:
            dpao_arr.remove(e)



#检查是否结束
def isovers():
    global isover
    if isover:
        texts="游戏结束"
        restart='重新开始'
        overtext=fonts.render(texts,True,(255,0,0))
        rest=fonts.render(restart,True,(0,255,0))
        screen.blit(overtext,(350,225))
        screen.blit(rest,(350,250))
        event=pygame.event.wait()
        # 是否点击重新开始
        if event.type==pygame.MOUSEBUTTONDOWN:
            x,y=event.pos
            if isover:
                if x>355 and x<400 and y>250 and y<300:
                    isover=False 
                    addenemy()

# boss
class Boss():
    def __init__(self):
        self.x=random.randint(0,700)
        self.y=random.randint(0,180)
        self.img=pygame.image.load(f'{path}/di2.png')
        self.step=3
boss_arr=[]
boss_num=0
def addboss():
    global boss_arr,boss_arr
    for i in range(boss_num):
        boss_arr.append(Boss())

# 显示boss
def showboss():
    global isover,dpao_arr
    for e in boss_arr:
        screen.blit(pygame.transform.scale(e.img,(40,60)),(e.x,e.y))
        #添加炮弹
        ispao=random.randint(0,100)
        if ispao ==6:
            dpao_arr.append(Dpao(e.x,e.y))
        showdipao()
        if e.x<0:
            e.x=0
            e.y+=10
            e.step=-e.step
        elif e.x >770:
            e.x=770
            e.y+=10
            e.step=-e.step
        if e.y>300:
            enemy_arr.clear()
            boss_arr.clear()
            isover=True
        e.x+=e.step


bao_arr=[]

# 爆炸类
class Bao():
    def __init__(self,x,y):
        self.images=[
            pygame.image.load(f'{path}/bao/b1.gif'),
            pygame.image.load(f'{path}/bao/b2.gif'),
            pygame.image.load(f'{path}/bao/b3.gif'),
            pygame.image.load(f'{path}/bao/b4.gif'),
            pygame.image.load(f'{path}/bao/b5.gif'),
            pygame.image.load(f'{path}/bao/b6.gif'),
            pygame.image.load(f'{path}/bao/b7.gif'),
            pygame.image.load(f'{path}/bao/b8.gif'),
            pygame.image.load(f'{path}/bao/b9.gif'),
            pygame.image.load(f'{path}/bao/b10.gif'),
            pygame.image.load(f'{path}/bao/b11.gif'),
            pygame.image.load(f'{path}/bao/b12.gif'),
            pygame.image.load(f'{path}/bao/b13.gif'),
            pygame.image.load(f'{path}/bao/b14.gif')
        ]
        # self.images=[
        #     pygame.image.load(f'{path}/bao/009.png'),
        #     pygame.image.load(f'{path}/bao/008.png'),
        #     pygame.image.load(f'{path}/bao/007.png'),
        #     pygame.image.load(f'{path}/bao/006.png'),
        #     pygame.image.load(f'{path}/bao/005.png'),
        #     pygame.image.load(f'{path}/bao/004.png'),
        #     pygame.image.load(f'{path}/bao/003.png'),
        #     pygame.image.load(f'{path}/bao/002.png'),
        #     pygame.image.load(f'{path}/bao/001.png'),
        #     pygame.image.load(f'{path}/bao/000.png'),
        # ]
        self.step=0
        self.img=self.images[self.step]
        self.live=True
        self.x=x-43
        self.y=y-4
    # 展示效果
    def showbao(self):
        if self.step<len(self.images):
            self.img=self.images[self.step]
            self.step+=1
            
            screen.blit(self.img,(self.x,self.y))
        else:
            self.live=False
            self.step=0


# 欧式距离检查是否碰撞
def distance(zx,zy,ex,ey):
    a=zx-ex
    b=zy-ey
    return math.sqrt(a*a+b*b)
# 保存子弹
zd_arr=[]
#子弹类
class Zidan():
    def __init__(self,x,y):
        self.x=x+5
        self.y=y+10
        self.img=pygame.image.load(f'{path}/zidan.png')
        self.step=random.randint(1,3)
    # 击中
    def hit(self):
        global score,boss_num
        # 击中敌人
        for e in enemy_arr:
            if (distance(self.x,self.y,e.x,e.y)<50):
                # 分数加1
                score+=1
                if score%6==0:
                    if len(boss_arr)<1:
                        if boss_num<1:
                            boss_num+=1
                        addboss()
                if score%3==0:
                    adddra()
                # 播放击中
                bao_sund.play()
                bao_arr.append(Bao(e.x,e.y))
                # 重置敌人位置重置类似消失
                e.reset()
                zd_arr.remove(self)
    def hitboss(self):
        # 击中boss
        global score,boss_arr
        for es in boss_arr:
            if (distance(self.x,self.y,es.x,es.y)<50):
                score+=1
                bao_sund.play()
                bao_arr.append(Bao(es.x,es.y))
                boss_arr.remove(es)

# 爆炸显示
def showbaos():
    for bao in bao_arr:
        if bao.live:
            bao.showbao()
        

def showzd():
    for z in zd_arr:
        screen.blit(z.img,(z.x,z.y))
        z.hit()
        z.hitboss()
        z.y-=z.step
        if z.y<0:
            zd_arr.remove(z)
        
runing=True


# 按键类
class Clis():
    def __init__(self,key):
        self.key=key
        self.cli_arr=[]
    def addcli(self):
        self.cli_arr.append(self)
    def recli(self):
        self.cli_arr.remove(self)
    def up(self):
        if len(self.cli_arr)!=0:
            # 两个键
            if len(self.cli_arr)==2:
                if self.cli_arr[0].type==pygame.K_RIGHT and self.cli_arr[1].type==pygame.K_SPACE:
                    print('sdfsd') 
            elif len(self.cli_arr)==1:
                pass

# 龙类
class Dragen():
    def __init__(self):
        self.images=[
            pygame.image.load(f'{path}/000.png'),
            pygame.image.load(f'{path}/001.png'),
            pygame.image.load(f'{path}/002.png'),
            pygame.image.load(f'{path}/003.png'),
            pygame.image.load(f'{path}/000.png'),
        ]
        self.x=0
        self.y=random.randint(0,350)
        self.step=0
    def fly(self):
        if self.step<len(self.images):
            # if 10%1000==0:
            self.img=self.images[self.step]
            screen.blit(self.img,(self.x,self.y))
            self.step+=1
            self.x+=1
        else:
            self.step=0
            self.img=self.images[self.step]
            screen.blit(self.img,(self.x,self.y))
            self.step+=1
            self.x+=1
    def crash(self):
        global isover
        if (distance(self.x,self.y,feix,feiy)<40):
            isover=True
            clearall()
# 存储龙
dra_num=1
dra_arr=[]
def adddra():
    for i in range(0,1):
        dra_arr.append(Dragen())
# 显示龙
def showdragen():
    for e in dra_arr:
        e.fly()
        e.crash()
        if e.x>700:
            dra_arr.remove(e)

def clearall():
    global enemy_arr,boss_arr,dra_arr
    enemy_arr.clear()
    boss_arr.clear()
    dra_arr.clear()
    
# 按键事件
def process():
    global zd_arr
    for event in pygame.event.get():
        global runing,num,num_up
        if event.type==pygame.QUIT:
            runing=False
        # 键盘按下
        if event.type==pygame.KEYDOWN:
            # 判断哪个键 
            if event.key==pygame.K_RIGHT:
                num=1
            elif event.key==pygame.K_LEFT:
                num=-1
            elif event.key==pygame.K_UP:
                num_up=-1
            elif event.key==pygame.K_DOWN:
                num_up=1
            elif event.key==pygame.K_SPACE:
                zd_arr.append(Zidan(feix,feiy))
        if event.type==pygame.KEYUP:
            num=0
            num_up=0
    
# 飞机类
class Feiji():
    def __init__(self):
        #左右
        self.num=0
        # 上下
        self.num_up=0
        # 初始位置
        self.feix=350
        self.feiy=400
        self.img=pygame.image.load(f'{path}/feiji.png')
        self.size=30
        # 按键存储1左2上3右4下
        self.key_list=[]

        pass
    def run(self):
        global feix,feiy
        self.feix+=self.num
        feix=self.feix
        self.feiy+=self.num_up
        feiy=self.feiy
        #出界问题
        if self.feix>770:
            self.feix=770
        elif self.feix<0:
            self.feix=0
        if self.feiy>415:
            self.feiy=415
        elif self.feiy<0:
            self.feiy=0
    def keyupdate(self):
        global runing
        for event in pygame.event.get():
            if event.type==pygame.QUIT:
                runing=False
            if event.type==pygame.KEYDOWN:
                if event.key==pygame.K_UP:
                    if pygame.K_UP in self.key_list:
                        self.key_list.remove(pygame.K_UP)
                    self.key_list.append(pygame.K_UP)
                elif event.key==pygame.K_DOWN:
                    if pygame.K_DOWN in self.key_list:
                        self.key_list.remove(pygame.K_DOWN)
                    self.key_list.append(pygame.K_DOWN)
                elif event.key==pygame.K_RIGHT:
                    if pygame.K_RIGHT in self.key_list:
                        self.key_list.remove(pygame.K_RIGHT)
                    self.key_list.append(pygame.K_RIGHT)
                elif event.key==pygame.K_LEFT:
                    if pygame.K_LEFT in self.key_list:
                        self.key_list.remove(pygame.K_LEFT)
                    self.key_list.append(pygame.K_LEFT)
                elif event.key==pygame.K_SPACE:
                    # self.key_list.append(pygame.K_SPACE)
                    zd_arr.append(Zidan(self.feix,self.feiy))
            elif event.type==pygame.KEYUP:
               
                if event.key==pygame.K_UP:
                    if pygame.K_UP in self.key_list:
                        self.key_list.remove(pygame.K_UP)
                    self.num_up=0
                elif event.key==pygame.K_RIGHT:
                    if pygame.K_RIGHT in self.key_list:
                        self.key_list.remove(pygame.K_RIGHT)
                    self.num=0
                elif event.key==pygame.K_DOWN:
                    if pygame.K_DOWN in self.key_list:
                        self.key_list.remove(pygame.K_DOWN)
                    self.num_up=0
                elif event.key==pygame.K_LEFT:
                    if pygame.K_LEFT in self.key_list:
                        self.key_list.remove(pygame.K_LEFT)
                    self.num=0
    
    def move(self):
        global zd_arr
        
        if len(self.key_list)==1:
            if self.key_list[0]==pygame.K_LEFT:
                self.num=-1
            elif self.key_list[0]==pygame.K_UP: 
                self.num_up=-1
            elif self.key_list[0]==pygame.K_RIGHT:
                self.num=1
            elif self.key_list[0]==pygame.K_DOWN:
                self.num_up= 1
        elif len(self.key_list)==2:
            if (self.key_list[0]==pygame.K_LEFT and self.key_list[1]==pygame.K_UP) or (self.key_list[1]==pygame.K_LEFT and self.key_list[0]==pygame.K_UP):
                self.num=-1
                self.num_up=-1
            elif (self.key_list[0]==pygame.K_RIGHT and self.key_list[1]==pygame.K_UP) or (self.key_list[1]==pygame.K_RIGHT and self.key_list[0]==pygame.K_UP):
                self.num=1
                self.num_up=-1
            elif (self.key_list[0]==pygame.K_RIGHT and self.key_list[1]==pygame.K_DOWN) or (self.key_list[1]==pygame.K_RIGHT and self.key_list[0]==pygame.K_DOWN):
                self.num=1
                self.num_up=1
            elif (self.key_list[0]==pygame.K_LEFT and self.key_list[1]==pygame.K_DOWN) or (self.key_list[1]==pygame.K_LEFT and self.key_list[0]==pygame.K_DOWN):
                self.num=-1
                self.num_up=1
# 飞机数据组
fei_arr=[]
# 飞机数据量
fei_num=1
# 添加飞机
for i in range(1):
    fei_arr.append(Feiji())
# 显示飞机
def showfeiji():
    for fe in fei_arr:
        screen.blit(pygame.transform.scale(fe.img,(fe.size,fe.size)),(fe.feix,fe.feiy))
        # 监听按键
        fe.keyupdate()
        # 按键响应
        fe.move()
        fe.run()


while runing:
    screen.blit(bg,(0,0))
    showfeiji()
    # process()
    showenemys()
    showzd()
    showboss()
    showdragen()
    showscore()
    showbaos()
    isovers()
   
    pygame.display.update()
    # 控制帧数
    # pygame.time.Clock().tick(10)